package com.dhcc.bpm.modules.api.controller;

import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.dhcc.bpm.common.annotation.Log;
import com.dhcc.bpm.common.constant.FilePathConstant;
import com.dhcc.bpm.common.enums.BusinessType;
import com.dhcc.bpm.common.json.JSONObject;
import com.dhcc.bpm.common.utils.ExcelUtil;
import com.dhcc.bpm.common.utils.FormatUtils;
import com.dhcc.bpm.common.utils.StringUtils;
import com.dhcc.bpm.modules.api.entity.Api;
import com.dhcc.bpm.modules.api.entity.Backservice;
import com.dhcc.bpm.modules.api.entity.BaseProduct;
import com.dhcc.bpm.modules.api.entity.Externalcall;
import com.dhcc.bpm.modules.api.service.*;
import com.dhcc.bpm.modules.api.vo.ApiVO;
import com.dhcc.bpm.modules.api.vo.BackserviceVO;
import com.dhcc.bpm.modules.api.vo.BaseProductVO;
import com.dhcc.bpm.modules.api.vo.ExternalcallVO;
import com.dhcc.bpm.modules.common.entity.Plupload;
import com.dhcc.bpm.modules.common.entity.Upload;
import com.dhcc.bpm.modules.common.service.IPluploadService;
import com.dhcc.bpm.modules.gateway.service.IGatewayRouteService;
import com.dhcc.bpm.modules.gateway.vo.GatewayRouteVO;
import com.dhcc.bpm.modules.log.service.IGatewayLogDayService;
import com.dhcc.bpm.modules.log.vo.AppApiViewVo;
import com.dhcc.bpm.modules.system.entity.SerialNumber;
import com.dhcc.bpm.modules.system.service.ISerialNumberService;
import com.google.common.collect.Lists;
import com.xkcoding.http.util.StringUtil;
import io.swagger.annotations.ApiOperation;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import io.swagger.annotations.ApiParam;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springblade.core.boot.ctrl.BladeController;
import org.springblade.core.log.annotation.ApiLog;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.mp.support.Query;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.Func;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @ClassName BaseProductController
 * @Description 基础产品表 控制器
 * @Author daina
 * @Date 2020/2/25 13:14
 * @Version V1.0
 * @Copyright: 2020 东华软件 . All rights reserved.
 */
@RestController
@AllArgsConstructor
@NoArgsConstructor
@RequestMapping("bpm-api/baseproduct")
public class BaseProductController extends BladeController {
    private static final Logger log = LoggerFactory.getLogger(ApiController.class);
    @Autowired
    private IBaseProductService baseProductService;
    @Autowired
    private IExternalcallService externalcallService;

    @Autowired
    private IPluploadService pluploadService;
    @Autowired
    private IBackserviceService backserviceService;
    @Autowired
    private IGatewayLogDayService gatewayLogDayService;
    @Autowired
    private IApiService apiService;
    @Autowired
    private ISysService sysService;
    @Autowired
    private IGatewayRouteService gatewayRouteService;
    @Autowired
    private ISerialNumberService serialNumberService;
    @Resource
    private StringRedisTemplate stringRedisTemplate;
    private String path;
    @Value("${bpm.file-public-path}")
    public void setFileUploadPath(String publicPath) {
        path = publicPath + FilePathConstant.SQLPATH;
    }

    private List<String> supportExcelType = Lists.newArrayList( "xls", "xlsx");

    /**
     * @param baseProduct
     * @return org.springblade.core.tool.api.R<com.dhcc.bpm.modules.api.entity.BaseProduct>
     * @Description 详情
     * @Author daina
     * @Date 14:49 2020/2/25
     **/
    @GetMapping("/detail")
    @ApiOperationSupport(order = 1)
    @ApiOperation(value = "基础产品详情", notes = "传入baseProduct")
    @Log(title = "基础产品详情", businessType = BusinessType.SELECT)
    @ApiLog("基础产品详情")
    public R<BaseProductVO> detail(BaseProductVO baseProduct) {
        //BaseProduct detail = baseProductService.getOne(Condition.getQueryWrapper(baseProduct));
        //BaseProduct detail = baseProductService.getById(baseProduct.getId());
        List<BaseProductVO> detailList = baseProductService.selectBackById(baseProduct.getId());
        BaseProductVO detail = detailList.get(0);
        String outIp = null;
        Plupload plupload = null;
        if (detail != null) {
            List<ExternalcallVO> externalcallvo = externalcallService.getByBackServiceId(detail.getBackId());
            if (externalcallvo != null && externalcallvo.size() > 0) {
                for (ExternalcallVO externalcall : externalcallvo) {
                    if(StringUtils.isBlank(externalcall.getCodePath()) && StringUtils.isBlank(externalcall.getServerCode())){
                        if (outIp != null) {
                            //修改时间 20201130 14：54：11 后端服务ip端口存储在一个字段ip里面
                            outIp = outIp + "," + externalcall.getIp() + ":" + externalcall.getPort();
//                        outIp = outIp + "," + externalcall.getIp();
                        } else {
                            //修改时间 20201130 14：54：11 后端服务ip端口存储在一个字段ip里面
                            outIp = externalcall.getIp() + ":" + externalcall.getPort();
//                        outIp = externalcall.getIp();
                        }
                    }

                }
            }
            //后端服务外部服务ip
            detail.setIp(outIp);
            detail.setServerStatus(stringRedisTemplate.opsForValue().get("third:serverStatus:" + detail.getProductNum()));

            //
            if("1".equals(detail.getIsTask()) && StringUtils.isNotBlank(detail.getTaskId())){
               String [] ids = detail.getTaskId().split(",");
               List<BaseProductVO.Task> list = new ArrayList<>();
                for (String id : ids) {
                    Externalcall externalcall = externalcallService.selectById(Long.valueOf(id));
                    if(null != externalcall){
                        BaseProductVO.Task task = new BaseProductVO.Task();
                        task.setIp(externalcall.getIp());
                        task.setPort(externalcall.getPort());
                        task.setCodePath(externalcall.getCodePath());
                        task.setServerCode(externalcall.getServerCode());
                        list.add(task);
                    }
                }
                detail.setTaskList(list);
            }

            // 报文配置文件 Xml add 2021-01-11
            if (null != detail.getXmlMsgConfig() && -1 != detail.getXmlMsgConfig()) {
                plupload = pluploadService.getById(detail.getXmlMsgConfig());
                if (plupload != null) {
                    detail.setXmlFileFullPath(plupload.getFileFullpath());
                    detail.setXmlFileRealname(plupload.getFileRealname());
                }
            }
            // 报文配置文件 Json add 2021-01-11
            if (null != detail.getJsonMsgConfig() && -1 != detail.getJsonMsgConfig()) {
                plupload = pluploadService.getById(detail.getJsonMsgConfig());
                if (plupload != null) {
                    detail.setJsonFileFullPath(plupload.getFileFullpath());
                    detail.setJsonFileRealname(plupload.getFileRealname());
                }
            }
            // 报文配置文件 Kv add 2021-01-11
            if (null != detail.getKvMsgConfig() && -1 != detail.getKvMsgConfig()) {
                plupload = pluploadService.getById(detail.getKvMsgConfig());
                if (plupload != null) {
                    detail.setKvFileFullPath(plupload.getFileFullpath());
                    detail.setKvFileRealname(plupload.getFileRealname());
                }
            }
            // 报文配置文件 Efet add 2021-01-11
            if (null != detail.getEfetMsgConfig() && -1 != detail.getEfetMsgConfig()) {
                plupload = pluploadService.getById(detail.getEfetMsgConfig());
                if (plupload != null) {
                    detail.setEfetFileFullPath(plupload.getFileFullpath());
                    detail.setEfetFileRealname(plupload.getFileRealname());
                }
            }
            // 报文配置文件 Fixed add 2021-01-11
            if (null != detail.getFixedMsgConfig() && -1 != detail.getFixedMsgConfig()) {
                plupload = pluploadService.getById(detail.getFixedMsgConfig());
                if (plupload != null) {
                    detail.setFixedFileFullPath(plupload.getFileFullpath());
                    detail.setFixedFileRealname(plupload.getFileRealname());
                }
            }
            // 报文配置文件 Sep add 2021-01-11
            if (null != detail.getSepMsgConfig() && -1 != detail.getSepMsgConfig()) {
                plupload = pluploadService.getById(detail.getSepMsgConfig());
                if (plupload != null) {
                    detail.setSepFileFullPath(plupload.getFileFullpath());
                    detail.setSepFileRealname(plupload.getFileRealname());
                }
            }
        }

        return R.data(detail);
    }



    /**
     * @param baseProduct
     * @param query
     * @return org.springblade.core.tool.api.R<com.baomidou.mybatisplus.core.metadata.IPage < com.dhcc.bpm.modules.api.entity.BaseProduct>>
     * @Description 分页 基础产品表
     * @Author daina
     * @Date 14:49 2020/2/25
     **/
    @GetMapping("/list")
    @ApiOperationSupport(order = 2)
    @ApiOperation(value = "分页", notes = "传入baseProduct")
    @Log(title = "基础产品分页", businessType = BusinessType.SELECT)
    @ApiLog("基础产品分页")
    public R<IPage<BaseProductVO>> list(BaseProductVO baseProduct, Query query) {
        IPage<BaseProductVO> pages = baseProductService.selectBProductList(Condition.getPage(query), baseProduct);

        if (pages.getRecords() != null && pages.getRecords().size() > 0) {

            for (BaseProductVO productVO : pages.getRecords()) {

                productVO.setServerStatus(stringRedisTemplate.opsForValue().get("third:serverStatus:" + productVO.getProductNum()));
                // 求成功率
                String successRateStr = "0.00";
                // 平均响应时间
                double avgResTime = 0.00;
                Long num = 0L;
                Long successNum = 0L;
                Long failNum = 0L;
                //----------------------基础产品对应的api----------------------
                ApiVO api = new ApiVO();
//                api.setProductId(productVO.getId().toString());
                api.setBackserviceId(productVO.getId());
//              api.setApiType(productVO.getBaseType());
                Query query2=new Query();
                query2.setSize(999);
                query2.setCurrent(0);
                IPage<ApiVO> page = apiService.listInfo(Condition.getPage(query2), api);
                // 统计信息  (响应次数、响应成功率、响应时间)
                if (page.getRecords() != null && page.getRecords().size() > 0) {
                    for (ApiVO apiVO : page.getRecords()) {
                        AppApiViewVo appApiViewVo = new AppApiViewVo();
                        appApiViewVo.setApiId(apiVO.getApiCode());
                        if(StringUtil.isEmpty(baseProduct.getEnv())){
                            appApiViewVo.setEnv("0"); // 环境标志  0-生产环境
                        }
                        if (baseProduct.getIsFrom()==1){
                            appApiViewVo.setBegDate(baseProduct.getBegDate());
                            appApiViewVo.setEndDate(baseProduct.getEndDate1());
                            appApiViewVo.setIsFrom(baseProduct.getIsFrom());
                        }
                        AppApiViewVo apiCountData = gatewayLogDayService.apiCount(appApiViewVo);
                        if (apiCountData != null) {
                            DecimalFormat df = new DecimalFormat("0.00");//格式化小数

                            double successRate = 0.00;
                            if (apiCountData.getRequestNum() != 0) {
                                successRate = (double) apiCountData.getSuccessNum() / apiCountData.getRequestNum() * 100;

                                successRateStr = FormatUtils.doubleFormat(Double.valueOf(successRateStr) + successRate);
                            }


                            if (apiCountData.getLineNum() != 0) {
                                double temp = Double.valueOf(df.format(apiCountData.getResponseTime() / apiCountData.getLineNum()));
                                avgResTime = Double.valueOf(df.format(avgResTime + temp));
                            }
                            num += apiCountData.getRequestNum();
                            successNum += apiCountData.getSuccessNum();
                            failNum += apiCountData.getFailRequestNum();
                        }
                    }
                }
                productVO.setNum(num);
                productVO.setSuccessNum(successNum);
                productVO.setFailNum(failNum);
                DecimalFormat df = new DecimalFormat("0.00");//格式化小数
                if (successRateStr.equals("0.00")) {
                    productVO.setSuccessRate("0.00%");
                } else {
                    double SuccessRate = Double.valueOf(successRateStr) / page.getRecords().size();
                    productVO.setSuccessRate(Double.valueOf(df.format(SuccessRate)) + "%");
                }

                if (avgResTime == 0.0) {
                    productVO.setResponseTime(Double.valueOf(0.00));
                } else {
                    productVO.setResponseTime(Double.valueOf(df.format(avgResTime / page.getRecords().size())));
                }

            }


        }

        return R.data(pages);
    }

    /**
     * @param baseProduct
     * @param query
     * @return org.springblade.core.tool.api.R<com.baomidou.mybatisplus.core.metadata.IPage < com.dhcc.bpm.modules.api.vo.BaseProductVO>>
     * @Description 自定义分页 基础产品表
     * @Author daina
     * @Date 14:49 2020/2/25
     **/
    @GetMapping("/page")
    @ApiOperationSupport(order = 3)
    @ApiOperation(value = "分页", notes = "传入baseProduct")
    @Log(title = "基础产品分页", businessType = BusinessType.SELECT)
    @ApiLog("基础产品分页")
    public R<IPage<BaseProductVO>> page(BaseProductVO baseProduct, Query query) {
        IPage<BaseProductVO> pages = baseProductService.selectBaseProductPage(Condition.getPage(query), baseProduct);

        if (pages.getRecords() != null && pages.getRecords().size() > 0) {

            for (BaseProductVO productVO : pages.getRecords()) {

                productVO.setServerStatus(stringRedisTemplate.opsForValue().get("third:serverStatus:" + productVO.getProductNum()));
                // 求成功率
                String successRateStr = "0.00";
                // 平均响应时间
                double avgResTime = 0.00;
                Long num = 0L;
                Long successNum = 0L;
                Long failNum = 0L;
                //----------------------基础产品对应的api----------------------
                ApiVO api = new ApiVO();
//                api.setProductId(productVO.getId().toString());
                api.setBackserviceId(productVO.getId());
//              api.setApiType(productVO.getBaseType());
                Query query2=new Query();
                query2.setSize(999);
                query2.setCurrent(0);
                IPage<ApiVO> page = apiService.listInfo(Condition.getPage(query2), api);
                // 统计信息  (响应次数、响应成功率、响应时间)
                if (page.getRecords() != null && page.getRecords().size() > 0) {
                    for (ApiVO apiVO : page.getRecords()) {
                        AppApiViewVo appApiViewVo = new AppApiViewVo();
                        appApiViewVo.setApiId(apiVO.getApiCode());
                        appApiViewVo.setEnv("0"); // 环境标志  0-生产环境
                        AppApiViewVo apiCountData = gatewayLogDayService.apiCount(appApiViewVo);
                        if (apiCountData != null) {
                            DecimalFormat df = new DecimalFormat("0.00");//格式化小数

                            double successRate = 0.00;
                            if (apiCountData.getRequestNum() != 0) {
                                successRate = (double) apiCountData.getSuccessNum() / apiCountData.getRequestNum() * 100;

                                successRateStr = FormatUtils.doubleFormat(Double.valueOf(successRateStr) + successRate);
                            }


                            if (apiCountData.getLineNum() != 0) {
                                double temp = Double.valueOf(df.format(apiCountData.getResponseTime() / apiCountData.getLineNum()));
                                avgResTime = Double.valueOf(df.format(avgResTime + temp));
                            }
                            num += apiCountData.getRequestNum();
                            successNum += apiCountData.getSuccessNum();
                            failNum += apiCountData.getFailRequestNum();
                        }
                    }
                }
                productVO.setNum(num);
                productVO.setSuccessNum(successNum);
                productVO.setFailNum(failNum);
                DecimalFormat df = new DecimalFormat("0.00");//格式化小数
                if (successRateStr.equals("0.00")) {
                    productVO.setSuccessRate("0.00%");
                } else {
                    double SuccessRate = Double.valueOf(successRateStr) / page.getRecords().size();
                    productVO.setSuccessRate(Double.valueOf(df.format(SuccessRate)) + "%");
                }

                if (avgResTime == 0.0) {
                    productVO.setResponseTime(Double.valueOf(0.00));
                } else {
                    productVO.setResponseTime(Double.valueOf(df.format(avgResTime / page.getRecords().size())));
                }

            }


        }
        return R.data(pages);
    }


    @GetMapping("/thirdPage")
    @ApiOperationSupport(order = 3)
    @ApiOperation(value = "第三方节点信息查询", notes = "传入baseProduct")
    @Log(title = "第三方节点信息查询", businessType = BusinessType.SELECT)
    @ApiLog("基础产品分页")
    public R<IPage<BaseProductVO>> thirdPage(BaseProductVO baseProduct, Query query) {
        IPage<BaseProductVO> pages = baseProductService.selectThirdBaseProductPage(Condition.getPage(query), baseProduct);

        if (pages.getRecords() != null && pages.getRecords().size() > 0) {

            for (BaseProductVO productVO : pages.getRecords()) {

                productVO.setServerStatus(stringRedisTemplate.opsForValue().get("third:serverStatus:" + productVO.getProductNum()));
                // 求成功率
                String successRateStr = "0.00";
                // 平均响应时间
                double avgResTime = 0.00;
                Long num = 0L;
                Long successNum = 0L;
                Long failNum = 0L;
                //----------------------基础产品对应的api----------------------
                ApiVO api = new ApiVO();
//                api.setProductId(productVO.getId().toString());
                api.setBackserviceId(productVO.getId());
//              api.setApiType(productVO.getBaseType());
                Query query2=new Query();
                query2.setSize(999);
                query2.setCurrent(0);
                IPage<ApiVO> page = apiService.listInfo(Condition.getPage(query2), api);
                // 统计信息  (响应次数、响应成功率、响应时间)
                if (page.getRecords() != null && page.getRecords().size() > 0) {
                    for (ApiVO apiVO : page.getRecords()) {
                        AppApiViewVo appApiViewVo = new AppApiViewVo();
                        appApiViewVo.setApiId(apiVO.getApiCode());
                        appApiViewVo.setEnv("0"); // 环境标志  0-生产环境
                        AppApiViewVo apiCountData = gatewayLogDayService.apiCount(appApiViewVo);
                        if (apiCountData != null) {
                            DecimalFormat df = new DecimalFormat("0.00");//格式化小数

                            double successRate = 0.00;
                            if (apiCountData.getRequestNum() != 0) {
                                successRate = (double) apiCountData.getSuccessNum() / apiCountData.getRequestNum() * 100;

                                successRateStr = FormatUtils.doubleFormat(Double.valueOf(successRateStr) + successRate);
                            }


                            if (apiCountData.getLineNum() != 0) {
                                double temp = Double.valueOf(df.format(apiCountData.getResponseTime() / apiCountData.getLineNum()));
                                avgResTime = Double.valueOf(df.format(avgResTime + temp));
                            }
                            num += apiCountData.getRequestNum();
                            successNum += apiCountData.getSuccessNum();
                            failNum += apiCountData.getFailRequestNum();
                        }
                    }
                }
                productVO.setNum(num);
                productVO.setSuccessNum(successNum);
                productVO.setFailNum(failNum);
                DecimalFormat df = new DecimalFormat("0.00");//格式化小数
                if (successRateStr.equals("0.00")) {
                    productVO.setSuccessRate("0.00%");
                } else {
                    double SuccessRate = Double.valueOf(successRateStr) / page.getRecords().size();
                    productVO.setSuccessRate(Double.valueOf(df.format(SuccessRate)) + "%");
                }

                if (avgResTime == 0.0) {
                    productVO.setResponseTime(Double.valueOf(0.00));
                } else {
                    productVO.setResponseTime(Double.valueOf(df.format(avgResTime / page.getRecords().size())));
                }

            }


        }
        return R.data(pages);
    }


    /**
     * @param api
     * @param query
     * @return org.springblade.core.tool.api.R<com.baomidou.mybatisplus.core.metadata.IPage < com.dhcc.bpm.modules.api.vo.ApiVO>>
     * @Description 自定义分页 查询基础产品关联的api列表
     * @Author daina
     * @Date 14:33 2020/2/25
     **/
    @GetMapping("/baseproductApi")
    @ApiOperationSupport(order = 3)
    @ApiOperation(value = "自定义分页 查询基础产品关联的api列表", notes = "传入api")
    @Log(title = "自定义分页 查询基础产品关联的api列表", businessType = BusinessType.SELECT)
    @ApiLog("自定义分页 查询基础产品关联的api列表")
    public R<IPage<ApiVO>> selectBaseProductApiList(ApiVO api, Query query) {
        IPage<ApiVO> pages = apiService.selectBaseProductApiList(Condition.getPage(query), api);
        return R.data(pages);
    }

    /**
     * @param baseProduct
     * @return org.springblade.core.tool.api.R
     * @Description 新增 基础产品表
     * @Author daina
     * @Date 14:50 2020/2/25
     **/
    @PostMapping("/save")
    @ApiOperationSupport(order = 4)
    @ApiOperation(value = "新增", notes = "传入baseProduct")
    @Log(title = "新增基础产品", businessType = BusinessType.INSERT)
    @ApiLog("新增基础产品")
    public R save(@Valid @RequestBody BaseProduct baseProduct) {
        return R.status(baseProductService.save(baseProduct));
    }

    /**
     * @param baseProduct
     * @return org.springblade.core.tool.api.R
     * @Description 修改 基础产品表
     * @Author daina
     * @Date 14:50 2020/2/25
     **/
    @PostMapping("/update")
    @ApiOperationSupport(order = 5)
    @ApiOperation(value = "修改", notes = "传入baseProduct")
    @Log(title = "修改基础产品", businessType = BusinessType.INSERT)
    @ApiLog("修改基础产品")
    public R update(@Valid @RequestBody BaseProduct baseProduct) {
        return R.status(baseProductService.updateById(baseProduct));
    }

    /**
     * @param baseProduct
     * @return org.springblade.core.tool.api.R
     * @Description 新增或修改 基础产品表
     * @Author daina
     * @Date 14:50 2020/2/25
     **/
    @PostMapping("/submit")
    @ApiOperationSupport(order = 6)
    @ApiOperation(value = "新增或修改", notes = "传入baseProduct")
    @Log(title = "新增或修改基础产品", businessType = BusinessType.INSERT)
    @ApiLog("新增或修改基础产品")
    @Transactional(rollbackFor = Exception.class)
    public R submit(@Valid @RequestBody BaseProductVO baseProduct/*, @RequestBody JSONObject obj*/) {
        //修改时间20200914 16:35
        SerialNumber serialNumber = null;
        Backservice backservice = null;
        String servicePath = null;
        Boolean bool = false;
        if (baseProduct.getId() != null) {
            //修改时间：20210508 修改原因：基础产品修改是不修改api信息 修改人：xiafayu
//            List<ApiVO> apiList = apiService.listByBackserviceId(baseProduct.getId());
//            if (apiList.size() > 0) {
//                for (ApiVO api : apiList) {
//                    if (null != api.getApiNum()) {
//                        String sysUrl = "";
//                        String baseProductUrl = "";
//                        Sys sys = sysService.getById(baseProduct.getOpcSysId());
//                        if (sys.getIsUrl() == 2) {
//                            sysUrl = sys.getUrl();
//                        } else {
//                            sysUrl = sys.getSysNum();
//                        }
//                        if (baseProduct.getIsUrl() == 2) {
//                            baseProductUrl = baseProduct.getUrl();
//                        } else {
//                            baseProductUrl = baseProduct.getProductNum();
//                        }
//                        api.setApiPath(("/prod/" + sysUrl + "/" + baseProductUrl + "/" + api.getApiNum()).replaceAll("//", "/") + "/V" + api.getApiVersion());
//                        api.setApiPathTest(("/sandbox/" + sysUrl + "/" + baseProductUrl + "/" + api.getApiNum()).replaceAll("//", "/") + "/V" + api.getApiVersion());
//                        boolean result = apiService.saveOrUpdate(api);
//                        List<GatewayRouteVO> routes = gatewayRouteService.getByApiId(api.getId().toString());
//                        for (GatewayRouteVO route : routes) {
//                            if ("1".equals(route.getEnv())) {
//                                route.setOpcGatewayId(api.getOpcGatewayId());
//                                route.setRouteConfig("[{\"predicateValue\":\"" + api.getApiPath() + "\",\"name\":\"Path\"}]");
//                            } else {
//                                route.setOpcGatewayId(api.getOpcGatewayIdTest());
//                                route.setRouteConfig("[{\"predicateValue\":\"" + api.getApiPathTest() + "\",\"name\":\"Path\"}]");
//                            }
//                            gatewayRouteService.saveOrUpdate(route);
//                        }
//                    }
//
//                }
//            }

            // 更新基础产品数据时修改流水表产品编码和名称 -----start-----  修改时间：20200914 16:17
//            BaseProduct basrpro = baseProductService.getById(baseProduct.getId());
//            serialNumber = serialNumberService.getSerialNumberByModelCode(basrpro.getProductNum());
//            if (serialNumber != null) {
//                serialNumber.setModuleCode(baseProduct.getProductNum());
//                serialNumber.setModuleName(baseProduct.getProductName());
//                serialNumberService.saveOrUpdate(serialNumber);
//            } else {
//                //新增产品是存到流水表中
//                serialNumber = new SerialNumber();
//                serialNumber.setModuleCode(baseProduct.getProductNum());//产品编码---唯一性
//                serialNumber.setModuleName(baseProduct.getProductName());
//                serialNumber.setMaxSerial("0");//开始的序列是0
//                serialNumber.setPreMaxNum("1");
//                serialNumber.setIsAutoIncrement("1");
//                serialNumber.setModelStatus("1");
//                serialNumber.setConfigTemplet("000");
//                serialNumber.setDescribe(baseProduct.getProductName());
//                serialNumberService.save(serialNumber);
//            }
            // --- end --- 修改时间：20200914 16:17
            List<BackserviceVO>  list = backserviceService.getByBaseProductId(baseProduct.getId());
            if (list.size() > 0){
                backservice = list.get(0);
                servicePath = backservice.getServicePath();
                bool = true;
            }

            //更新基础产品下面的api的报文id
            List<ApiVO> apiLists = apiService.getListByProductId(baseProduct.getId());
            apiLists.forEach(apiVO -> {
                if("1".equals(apiVO.getBackserviceReqType())){
                    apiVO.setJsonMsgConfig(baseProduct.getJsonMsgConfig());
                }
                if("2".equals(apiVO.getBackserviceReqType())){
                    apiVO.setXmlMsgConfig(baseProduct.getXmlMsgConfig());
                }
                if("3".equals(apiVO.getBackserviceReqType())){
                    apiVO.setSepMsgConfig(baseProduct.getSepMsgConfig());
                }
                if("4".equals(apiVO.getBackserviceReqType())){
                    apiVO.setFixedMsgConfig(baseProduct.getFixedMsgConfig());
                }
                if("5".equals(apiVO.getBackserviceReqType())){
                    apiVO.setEfetMsgConfig(baseProduct.getEfetMsgConfig());
                }
                apiService.saveOrUpdate(apiVO);
            });

        } else {
//            //新增产品是存到流水表中
//            serialNumber = new SerialNumber();
//            serialNumber.setModuleCode(baseProduct.getProductNum());//产品编码---唯一性
//            serialNumber.setModuleName(baseProduct.getProductName());
//            serialNumber.setMaxSerial("0");//开始的序列是0
//            serialNumber.setPreMaxNum("1");
//            serialNumber.setIsAutoIncrement("1");
//            serialNumber.setModelStatus("1");
//            serialNumber.setConfigTemplet("000");
//            serialNumber.setDescribe(baseProduct.getProductName());
//            serialNumberService.save(serialNumber);

        }

        baseProductService.saveOrUpdate(baseProduct);

        if (null == backservice) {
            backservice = new Backservice();
            String code = serialNumberService.generateSerialNumberByModelCode("opc_backservice");
            // safeType 安全认证类型 0：签名加密 ； 1：签名；  2：加密 ； 3：明文
            backservice.setSafeType(0L);
            backservice.setBackserviceCode(code);
        }
        boolean status;
        try {
            //服务名去除空格  修改时间：20201026 09:20
            if (baseProduct.getApplicationName() != null) {
                backservice.setApplicationName(baseProduct.getApplicationName().trim().replaceAll(" ", ""));
            }
            backservice.setBackserviceEname(baseProduct.getProductEname());
            backservice.setBackserviceName(baseProduct.getProductName());
            backservice.setApplyType(baseProduct.getApplyType());
            backservice.setAccessProtocol(baseProduct.getAccessProtocol());
            backservice.setMsgCode(baseProduct.getMsgCode());
            backservice.setBaseProductId(baseProduct.getId());
            backservice.setBackserviceType(baseProduct.getBackserviceType());
            //增加后端服务统一路径
            backservice.setServicePath(baseProduct.getServicePath());
            backservice.setIsTask(baseProduct.getIsTask());

            //删除后端服务外部调用数据
            if (backservice.getId() != null){
                externalcallService.getByBackServiceId(backservice.getId()).forEach(externalcallVO -> {
                    externalcallService.removeById(externalcallVO.getId());
                });
            }
            String taskId = "";
            if("1".equals(baseProduct.getIsTask())){
                for (BaseProductVO.Task task : baseProduct.getTaskList()) {
                    Externalcall ec = new Externalcall();
                    ec.setBackserviceId(backservice.getId());
                    ec.setIp(task.getIp());
                    ec.setPort(task.getPort());
                    ec.setServerCode(task.getServerCode());
                    ec.setCodePath(task.getCodePath());
                    ec.setExpSeq(stringRedisTemplate.opsForValue().get("expSeq"));
                    externalcallService.saveOrUpdate(ec);
                    taskId = ec.getId() + "," + taskId;
                }
            }
            if(!"".equals(taskId)){
                taskId = taskId.substring(0,taskId.length() -1);
            }
            //变更后端服务路径修改基础产品下的路由路径  修改时间：20210618 11:16
            final String path = servicePath;
            if(bool && null != servicePath && !servicePath.equals(baseProduct.getServicePath())){
                List<ApiVO> apiList = apiService.listByBackserviceId(baseProduct.getId());
                for(Api api: apiList){
                    List<GatewayRouteVO> routes = gatewayRouteService.getByApiId(api.getId().toString());
                    routes = routes.stream().filter((GatewayRouteVO gatewayRoute) ->
                            gatewayRoute.getFilters().indexOf("\"name\":\"SetPath\"") > -1)
                            .collect(Collectors.toList());
                    routes.forEach(gatewayRoute ->{
                        JSONArray jsonArray = new JSONArray();
                        JSONArray array = JSONArray.parseArray(gatewayRoute.getFilters());
                        Iterator iterator = array.stream().iterator();
                        if (iterator.hasNext()){
                            com.alibaba.fastjson.JSONObject json = com.alibaba.fastjson.JSONObject.parseObject(iterator.next().toString());
                            if("SetPath".equals(json.getString("name"))){
                                String filterValue = json.getString("filterValue");
                                if(!"/".equals(path) && StringUtil.isNotEmpty(path)){
                                    if(filterValue.startsWith(path)){
                                        filterValue = filterValue.replace(path, baseProduct.getServicePath());
                                    }
                                }else{
                                    filterValue = "/" + baseProduct.getServicePath() + "/" + filterValue;
                                }
                                json.put("filterValue", filterValue.replace("//", "/"));
                                jsonArray.add(json);
                            }
                        }
                        gatewayRoute.setFilters(jsonArray.toJSONString());
                        gatewayRouteService.saveOrUpdate(gatewayRoute);
                    });
                }
            }
            backservice.setTaskId(taskId);
            status = backserviceService.saveOrUpdate(backservice);
        } catch (Exception e) {
            log.error("异常信息：{}", e);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            if (e.getMessage().contains("for key 'backservice_name_idx'") || e.getMessage().contains("ORA-00001")) {
                return R.fail(500, "该后端服务已存在");
            }
            return R.fail(500, "数据库异常");
        } finally {

        }


        //  applyType 服务调用类型(1：内部调用，2：外部调用)
        String applyType = "2";
        if (backservice.getApplyType().equals(applyType)) {
//            JSONObject.JSONArray list = obj.getArr("excallKeysNames");
//            JSONObject.JSONArray portList = obj.getArr("excallKeysPort");
           List<String> list = baseProduct.getExcallKeysNames();
            List<String> portList = baseProduct.getExcallKeysPort();
            if (status && null != list && list.size() > 0) {
                Externalcall ec = new Externalcall();
                ec.setBackserviceId(backservice.getId());
                for (int i = 0; i < list.size(); i++) {
                    //修改时间 20201130 14：54：11 后端服务ip端口存储在一个字段ip里面
//                    String[] str = list.get(i).split(":");
//                    ec.setIp(str[0]);
//                    ec.setPort(Long.valueOf(str[1]));
                    ec.setIp(list.get(i));
                    ec.setPort(Long.valueOf(portList.get(i)));
                    ec.setExpSeq(stringRedisTemplate.opsForValue().get("expSeq"));
                    externalcallService.saveOrUpdate(ec);
                    ec.setId(null);
                }
            }
        }
        if (status) {
            baseProductService.saveOrUpdate(baseProduct);
        }
        return R.data(baseProduct);
    }


    /**
     * @param ids
     * @return org.springblade.core.tool.api.R
     * @Description 删除 基础产品表
     * @Author daina
     * @Date 14:50 2020/2/25
     **/
    @PostMapping("/remove")
    @ApiOperationSupport(order = 7)
    @ApiOperation(value = "逻辑删除", notes = "传入ids")
    @Log(title = "删除基础产品", businessType = BusinessType.DELETE)
    @ApiLog("删除基础产品")
    @Transactional(rollbackFor = Exception.class)
    public R remove(@ApiParam(value = "主键集合", required = true) @RequestParam String ids) {
        List<Long> list = Func.toLongList(ids);
        for (Long data : list) {
            Api api = new Api();
            api.setBackserviceId(data);
            List<Api> apiList = apiService.list(Condition.getQueryWrapper(api));
            if (apiList.size() > 0) {
                //说明改基础产品下还有api
                return R.fail(267, "此产品下存在已有API信息!");
            }
            //删除基础产品时删除后端服务信息
            backserviceService.deleteByBaseProductId(data);
            externalcallService.deleteByBaseProductId(data);
        }
        return R.status(baseProductService.deleteLogic(Func.toLongList(ids)));
    }

    /**
     * @param
     * @return com.dhcc.bpm.common.json.JSONObject
     * @Description 系统服务名关联查询
     * @Author daina
     * @Date 14:50 2020/2/25
     **/
    @GetMapping("/selectBaseProductName")
    @ApiOperationSupport(order = 8)
    @ApiOperation(value = "基础产品名关联查询", notes = "无参")
    @ApiLog("基础产品名关联查询")
    @Log(title = "基础产品名关联查询", businessType = BusinessType.SELECT)
    public JSONObject selectBySysName() {
        JSONObject object = new JSONObject();
        object.put("success", true);
        object.put("names", baseProductService.selectBaseProductName());
        return object;
    }

    /**
     * @param productNum
     * @return java.util.List<com.dhcc.bpm.modules.api.vo.BaseProductVO>
     * @throws
     * @Description 编码判断是否重复
     * @Author xiafayu
     * @Date 2020/3/21 20:18
     **/
    @ApiLog("查询产品编码")
    @PostMapping("/selectBySysNum")
    @ApiOperationSupport(order = 7)
    @ApiOperation(value = "查询产品编码", notes = "sysNum")
    @Log(title = "查询产品编码", businessType = BusinessType.SELECT)
    public R selectBySysNum(@ApiParam(value = "产品编码", required = true) @RequestParam String productNum) {
        List<BaseProductVO> list = baseProductService.selectBySysNum(productNum);
        if (list.size() > 0) {
            return R.data(false);
        }
        return R.data(true);
    }

    @PostMapping("/download")
    public void download(BaseProductVO baseProduct, HttpServletResponse response) {
        int page = 1;
        List<BaseProductVO> BaseProductVO = new ArrayList<>();
        while (true) {
            Query query = new Query();
            query.setCurrent(page++);
            query.setSize(10);
            IPage<BaseProductVO> pages = baseProductService.selectBaseProductPage(Condition.getPage(query), baseProduct);
            // 统计api 信息  (响应次数、响应成功率、响应时间)
            if (pages.getRecords() != null && pages.getRecords().size() > 0) {
                BaseProductVO.addAll(pages.getRecords());
            } else {
                break;
            }
        }


        ExcelUtil<BaseProductVO> util = new ExcelUtil<BaseProductVO>(BaseProductVO.class);
        util.exportExcel(BaseProductVO, "API基础产品信息表", response);
    }

    @ApiLog("导入excel")
    @ApiOperationSupport(order = 7)
    @ApiOperation(value = "导入excel", notes = "sysNum")
    @Log(title = "导入excel", businessType = BusinessType.SELECT)
    @PostMapping("importexcel")
    public R importexcel(Plupload plupload, HttpServletRequest request) {
        String name = null;
        Upload upload = new Upload();
        upload.setRequest(request);
        Upload uploadEntity = pluploadService.getFile(upload);
        MultipartFile file = uploadEntity.getMultipartFile();
        name = file.getOriginalFilename();
        String fileType = name.substring(name.lastIndexOf(".") + 1);
        if(!supportExcelType.contains(fileType)){
            return R.fail("请上传excel类型文档！");
        }
        uploadEntity.setName(name);
        //本地上传
        String id = pluploadService.fileLocalUpload(plupload, upload, request).toString();
        Plupload newupload = pluploadService.selectById(Long.parseLong(id));
        try (InputStream inputStream = new FileInputStream(new File(path + "/"  + newupload.getFileRealname()))) {
            ExcelUtil<Api> excelUtil = new ExcelUtil<Api>(Api.class);
            List<Api> list = excelUtil.importExcel("API发布信息表", inputStream);
            for (Api sys : list) {
                try {
                    apiService.save(sys);
                } catch (Exception e) {
                    log.error("数据库异常：{}", e);
                    if (e.getMessage().contains("for key 'sys_name_idx'") || e.getMessage().contains("ORA-00001")) {
                        continue;
                    } else {
                        return R.fail(500, "数据库异常");
                    }
                } finally {

                }
            }
            pluploadService.fileDelete(Long.parseLong(id));
        } catch (FileNotFoundException e) {
            log.error("异常信息:{}", e);
        } catch (Exception e) {
            log.error("异常信息:{}", e);
        }
        return R.success("导入成功");
    }

}
